package com.example.launibleplugin.protocol

import android.util.Log
import java.text.SimpleDateFormat
import java.util.*

/**
 * 呼吸家设备协议处理器
 * Function: 处理呼吸家设备的字符串协议通信
 * Note: 根据呼吸家蓝牙开发手册实现协议解析和生成
 */
class RespiratoryProtocolHandler {
    
    companion object {
        private const val TAG = "RespiratoryProtocol"
        
        // 协议命令
        const val CMD_HANDSHAKE = "db_sk_b1_ip"
        const val CMD_MEASUREMENT = "db_sk_b1_cmd"
        const val CMD_DATA_REPORT = "db_sk_report_info_b1"
        const val CMD_CONTROL = "db_sk_b1_cmd"
        const val CMD_AX_DATE = "db_ax_date"
        const val CMD_AX_FVC = "db_ax_fvc"
        
        // 协议参数
        const val TERMINAL_TYPE = "0b1"
        const val PROTOCOL_VERSION = "B8.01"
        const val CHANNEL_ID = "1"
        
        // 日期格式
        private val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
    }
    
    /**
     * Function: 解析接收到的协议数据
     * Parameter: data - 接收到的字符串数据
     * Return: ProtocolMessage? - 解析后的协议消息
     * Note: 解析呼吸家设备发送的协议数据
     */
    fun parseProtocolMessage(data: String): ProtocolMessage? {
        try {
            Log.d(TAG, "解析协议数据: $data")
            
            // 移除结束符
            val cleanData = data.replace("\r\n", "").replace(",da", "")
            
            if (!cleanData.startsWith("#")) {
                Log.w(TAG, "协议数据格式错误，缺少起始符")
                return null
            }
            
            val parts = cleanData.substring(1).split(",")
            if (parts.isEmpty()) {
                Log.w(TAG, "协议数据为空")
                return null
            }
            
            val command = parts[0]
            Log.d(TAG, "识别协议命令: $command, 字段数量: ${parts.size}")
            
            return when (command) {
                CMD_AX_DATE -> {
                    Log.d(TAG, "解析AX_DATE协议")
                    parseAxDateMessage(parts)
                }
                CMD_AX_FVC -> {
                    Log.d(TAG, "解析AX_FVC协议")
                    parseAxFvcMessage(parts)
                }
                CMD_HANDSHAKE -> {
                    if (parts.size < 6) {
                        Log.w(TAG, "握手协议数据字段不足")
                        return null
                    }
                    val imei = parts[2]
                    parseHandshakeMessage(parts, imei)
                }
                CMD_DATA_REPORT -> {
                    if (parts.size < 6) {
                        Log.w(TAG, "数据报告协议字段不足")
                        return null
                    }
                    val imei = parts[2]
                    parseDataReportMessage(parts, imei)
                }
                else -> {
                    Log.w(TAG, "未知协议命令: $command")
                    null
                }
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "解析协议数据异常", e)
            return null
        }
    }
    
    /**
     * Function: 解析握手协议消息
     * Parameter: parts - 协议字段数组
     * Parameter: imei - 设备IMEI
     * Return: HandshakeMessage - 握手消息对象
     */
    private fun parseHandshakeMessage(parts: List<String>, imei: String): HandshakeMessage {
        return HandshakeMessage(
            imei = imei,
            terminalType = parts[1],
            protocolVersion = parts[3],
            channelId = parts[4],
            messageLength = parts[5].toIntOrNull() ?: 0
        )
    }
    
    /**
     * Function: 解析数据报告消息
     * Parameter: parts - 协议字段数组
     * Parameter: imei - 设备IMEI
     * Return: DataReportMessage - 数据报告消息对象
     */
    private fun parseDataReportMessage(parts: List<String>, imei: String): DataReportMessage? {
        if (parts.size < 23) {
            Log.w(TAG, "数据报告消息字段不足")
            return null
        }
        
        return try {
            DataReportMessage(
                imei = imei,
                terminalType = parts[1],
                protocolVersion = parts[3],
                channelId = parts[4],
                messageLength = parts[5].toIntOrNull() ?: 0,
                totalDataCount = parts[6].toIntOrNull() ?: 0,
                currentDataIndex = parts[7].toIntOrNull() ?: 0,
                dataTime = parts[8],
                gender = parts[9].toIntOrNull() ?: 0,
                age = parts[10].toIntOrNull() ?: 0,
                height = parts[11].toIntOrNull() ?: 0,
                weight = parts[12].toIntOrNull() ?: 0,
                pefValue = parts[13].toIntOrNull() ?: 0,
                fev1Value = parts[14].toDoubleOrNull() ?: 0.0,
                fvcValue = parts[15].toDoubleOrNull() ?: 0.0,
                mef75Value = parts[16].toDoubleOrNull() ?: 0.0,
                mef50Value = parts[17].toDoubleOrNull() ?: 0.0,
                mef25Value = parts[18].toDoubleOrNull() ?: 0.0,
                mmefValue = parts[19].toDoubleOrNull() ?: 0.0,
                reserved = parts[20],
                curveData = if (parts.size > 21) parts[21] else ""
            )
        } catch (e: Exception) {
            Log.e(TAG, "解析数据报告消息异常", e)
            null
        }
    }
    
    /**
     * Function: 生成测量指令
     * Parameter: imei - 设备IMEI
     * Parameter: protocolVersion - 协议版本
     * Parameter: commandCode - 命令码（1-开始测量，2-取消测量）
     * Return: String - 测量指令字符串
     * Note: 根据呼吸家协议生成测量控制指令
     */
    fun generateMeasurementCommand(imei: String, protocolVersion: String, commandCode: Int): String {
        val command = buildString {
            append("#")
            append(CMD_MEASUREMENT)
            append(",")
            append("0b1") // 终端类型
            append(",")
            append(imei) // IMEI
            append(",")
            append(protocolVersion) // 协议版本
            append(",")
            append(commandCode) // 控制命令码
            append(",")
            append("7") // 消息长度
            append(",")
            append("0") // CRC校验码（暂不校验）
            append(",da")
        }
        
        Log.d(TAG, "生成测量指令: $command")
        return command
    }
    
    /**
     * Function: 生成握手响应消息
     * Parameter: request - 握手请求消息
     * Return: String - 响应消息字符串
     * Note: 根据呼吸家协议生成握手响应
     */
    fun generateHandshakeResponse(request: HandshakeMessage): String {
        val currentTime = DATE_FORMAT.format(Date())
        
        val response = buildString {
            append("#")
            append(CMD_HANDSHAKE)
            append(",")
            append(request.terminalType)
            append(",")
            append(request.imei)
            append(",")
            append(request.protocolVersion)
            append(",")
            append(request.channelId)
            append(",")
            append("20") // 消息长度
            append(",")
            append("1") // 结果：1-成功
            append(",")
            append("234") // PEF预计值
            append(",")
            append("1.23") // FEV1预计值
            append(",")
            append("1.24") // FVC预计值
            append(",")
            append("0.01") // PEF系数
            append(",")
            append("-0.01") // FEV1系数
            append(",")
            append("0.01") // FVC系数
            append(",")
            append("0") // 性别：0-男
            append(",")
            append("25") // 年龄
            append(",")
            append("175") // 身高
            append(",")
            append("70") // 体重
            append(",")
            append("0") // 设备更新标志
            append(",")
            append(currentTime) // 当前时间
            append(",")
            append("0") // CRC校验码（暂不校验）
            append("\r\n")
        }
        
        Log.d(TAG, "生成握手响应: $response")
        return response
    }
    
    /**
     * Function: 生成数据报告响应消息
     * Parameter: request - 数据报告请求消息
     * Return: String - 响应消息字符串
     * Note: 生成db_sk_report_info_b1协议的响应消息
     */
    fun generateDataReportResponse(request: DataReportMessage): String {
        val response = buildString {
            append("#")
            append(CMD_DATA_REPORT)
            append(",")
            append(request.terminalType)
            append(",")
            append(request.imei)
            append(",")
            append(request.protocolVersion)
            append(",")
            append(request.channelId)
            append(",")
            append("11") // 消息长度
            append(",")
            append("1") // 结果：1-成功
            append(",")
            append("0") // PEF结果提示：0-正常
            append(",")
            append("0") // FEV1结果提示：0-正常
            append(",")
            append("0") // FVC结果提示：0-正常
            append(",")
            append("0") // CRC校验码
            append("\r\n")
        }
        
        Log.d(TAG, "生成数据报告响应: $response")
        return response
    }
    
    /**
     * Function: 解析日期时间消息
     * Parameter: parts - 协议字段数组
     * Return: AxDateMessage - 日期时间消息对象
     * Note: 解析db_ax_date协议数据
     */
    private fun parseAxDateMessage(parts: List<String>): AxDateMessage? {
        if (parts.size < 5) {
            Log.w(TAG, "日期时间消息字段不足")
            return null
        }
        
        return try {
            AxDateMessage(
                command = parts[0],
                param1 = parts[1].toIntOrNull() ?: 0,
                param2 = parts[2].toIntOrNull() ?: 0,
                param3 = parts[3].toIntOrNull() ?: 0,
                timeData = parts[4],
                checksum = if (parts.size > 5) parts[5] else ""
            )
        } catch (e: Exception) {
            Log.e(TAG, "解析日期时间消息异常", e)
            null
        }
    }
    
    /**
     * Function: 解析FVC测量数据消息
     * Parameter: parts - 协议字段数组
     * Return: AxFvcMessage - FVC测量数据消息对象
     * Note: 解析db_ax_fvc协议数据
     */
    private fun parseAxFvcMessage(parts: List<String>): AxFvcMessage? {
        if (parts.size < 20) {
            Log.w(TAG, "FVC测量数据消息字段不足")
            return null
        }
        
        return try {
            AxFvcMessage(
                command = parts[0],
                testNumber = parts[1].toIntOrNull() ?: 0,
                testCount = parts[2].toIntOrNull() ?: 0,
                pef = parts[3].toDoubleOrNull() ?: 0.0,
                fev1 = parts[4].toDoubleOrNull() ?: 0.0,
                fev025 = parts[5].toDoubleOrNull() ?: 0.0,
                fvc = parts[6].toDoubleOrNull() ?: 0.0,
                mef75 = parts[7].toDoubleOrNull() ?: 0.0,
                mef50 = parts[8].toDoubleOrNull() ?: 0.0,
                mef25 = parts[9].toDoubleOrNull() ?: 0.0,
                mmef = parts[10].toDoubleOrNull() ?: 0.0,
                fev1_fvc = parts[11].toDoubleOrNull() ?: 0.0,
                fet = parts[12].toDoubleOrNull() ?: 0.0,
                temperature = parts[13].toDoubleOrNull() ?: 0.0,
                pressure = parts[14].toIntOrNull() ?: 0,
                humidity = parts[15].toIntOrNull() ?: 0,
                reserved1 = parts[16].toIntOrNull() ?: 0,
                heartRate = parts[17].toIntOrNull() ?: 0,
                oxygenSaturation = parts[18].toIntOrNull() ?: 0,
                testQuality = parts[19].toIntOrNull() ?: 0,
                checksum = if (parts.size > 20) parts[20] else ""
            )
        } catch (e: Exception) {
            Log.e(TAG, "解析FVC测量数据消息异常", e)
            null
        }
    }
}

/**
 * 协议消息基类
 */
sealed class ProtocolMessage

/**
 * 握手消息
 */
data class HandshakeMessage(
    val imei: String,
    val terminalType: String,
    val protocolVersion: String,
    val channelId: String,
    val messageLength: Int
) : ProtocolMessage()

/**
 * 数据报告消息
 */
data class DataReportMessage(
    val imei: String,
    val terminalType: String,
    val protocolVersion: String,
    val channelId: String,
    val messageLength: Int,
    val totalDataCount: Int,
    val currentDataIndex: Int,
    val dataTime: String,
    val gender: Int,
    val age: Int,
    val height: Int,
    val weight: Int,
    val pefValue: Int,
    val fev1Value: Double,
    val fvcValue: Double,
    val mef75Value: Double,
    val mef50Value: Double,
    val mef25Value: Double,
    val mmefValue: Double,
    val reserved: String,
    val curveData: String
) : ProtocolMessage()

/**
 * 日期时间消息
 */
data class AxDateMessage(
    val command: String,
    val param1: Int,
    val param2: Int,
    val param3: Int,
    val timeData: String,
    val checksum: String
) : ProtocolMessage()

/**
 * FVC测量数据消息
 */
data class AxFvcMessage(
    val command: String,
    val testNumber: Int,
    val testCount: Int,
    val pef: Double,        // 呼气峰流速
    val fev1: Double,       // 第一秒用力呼气量
    val fev025: Double,     // 0.25秒用力呼气量
    val fvc: Double,        // 用力肺活量
    val mef75: Double,      // 75%肺活量时的最大呼气流速
    val mef50: Double,      // 50%肺活量时的最大呼气流速
    val mef25: Double,      // 25%肺活量时的最大呼气流速
    val mmef: Double,       // 平均最大呼气流速
    val fev1_fvc: Double,   // FEV1/FVC比值
    val fet: Double,        // 用力呼气时间
    val temperature: Double, // 温度
    val pressure: Int,      // 气压
    val humidity: Int,      // 湿度
    val reserved1: Int,     // 保留字段1
    val heartRate: Int,     // 心率
    val oxygenSaturation: Int, // 血氧饱和度
    val testQuality: Int,   // 测试质量
    val checksum: String    // 校验码
) : ProtocolMessage()